#include "disparition.h"
#include "QVBoxLayout"
#include <QDebug>
#include "vtable.h"
#include "textedit.h"
#include "protocol.h"
#include "DbConnection.h"
#include "treedoc.h"

Disparition::Disparition(MacAction *Parent): DocEntity(Parent)
{
    DbConnection::QueryResult res = dynamic_cast<TreeDoc*>(treeWidget())
                                    ->execute("select * from =schema=.ex_operations where element_type=2");
    if(res.success())
    {
        for(int i=0;i<res.rows();i++)
        {
            QAction* action = new QAction(res.at(i,2).toString(),this);
            if(res.at(i,1).toInt()==3)
            {
                connect(action,SIGNAL(triggered()),this,SLOT(appendProtocol()));
                action->setIcon(QIcon(":/add_entity"));
            }
            if(res.at(i,1).toInt()==6)
            {
                connect(action,SIGNAL(triggered()),this,SLOT(save()));
                action->setIcon(QIcon(":/save_entity"));
            }
            if(res.at(i,1).toInt()==10)
            {
                connect(action,SIGNAL(triggered()),this,SLOT(remove()));
                action->setIcon(QIcon(":/delete_entity"));
            }
            if(action!=0) operations()->addOperation(res.at(i,1).toInt(),action);
        }
        QAction* action = new QAction(QIcon(":/refresh"),tr("Обновить"),this);
        connect(action,SIGNAL(triggered()),this,SLOT(refresh()));
        operations()->addOperation(50,action);
        operations()->setEnabled(50,true);
    }
}
bool Disparition::removeFromDB()
{
    return dynamic_cast<TreeDoc*>(treeWidget())
                                    ->execute(tr("select =schema=.ex_delete_disparition(%1)").arg(id())).success();
}
void Disparition::giveBithTo()
{
    TreeDoc* tree= dynamic_cast<TreeDoc*>(treeWidget());
    DbConnection::QueryResult res= tree->
                              execute(tr("select * from =schema=.ex_protocols where disparition=%1").arg(id()));
    if(res.success())
    for(int i=0;i<res.rows();i++)
    {
        Protocol* item=new Protocol(this);
        item->blockSignals(true);
        item->setID(res.at(i,0).toInt());
        item->setNum(res.at(i,2).toInt());
        item->setCauses(res.at(i,3).toString());
        item->setAuthor(tree->users()->user(res.at(i,4).toInt()));
        item->setState(res.at(i,6).toInt());
        item->blockSignals(false);
        if(dynamic_cast<TreeDoc*>(treeWidget())->highlight()) emit newItem(item);
        QStringList ops = res.at(i,7).toString().replace(QRegExp("[{}]"),"").split(",",QString::SkipEmptyParts);
        if(ops.count()==0) continue;
        foreach(QString id,ops) item->operations()->setEnabled(id.toInt(),true);
    }
}
void Disparition::refresh(const RefreshType &refreshType)
{

        DbConnection::QueryResult res=dynamic_cast<TreeDoc*>(treeWidget())->
                                  execute(tr("select * from =schema=.ex_disparitions where eid=%1").arg(id()));
        if(res.success())
        {
            blockSignals(true);
            setID(res.at(0,0).toInt());
            setNum(res.at(0,2).toInt());
            setContent(res.at(0,3).toString());
            setState(res.at(0,4).toInt());
            blockSignals(false);
            operations()->turnOff();
            operations()->setEnabled(50,true);
            QStringList ops = res.at(0,5).toString().replace(QRegExp("[{}]"),"").split(",",QString::SkipEmptyParts);
            if(ops.count()>0)
            foreach(QString id,ops) operations()->setEnabled(id.toInt(),true);
        }
    if(refreshType==Himself)
    {
        emit wasRefresh();
        emit childWakedUp(this);
    }
    if(refreshType==Children)
    {
        for(int i=0;i<childCount();i++)
            dynamic_cast <Protocol*>(child(i))->refresh(Children);
    }
}
QWidget* Disparition::view(DocEntity::ViewTypes viewType)
{
    QWidget* widget = new QWidget(treeWidget());
    QVBoxLayout* main = new QVBoxLayout;
    QVBoxLayout* vlay = new QVBoxLayout;
    main->setContentsMargins(0,0,0,0);
    QGroupBox* gbox = new QGroupBox(text(0),widget);
    gbox->setLayout(vlay);
    TextEdit* w_content = new TextEdit(widget);
    w_content->blockSignals(true);
    w_content->setText(m_content);
    connect(w_content,SIGNAL(textChanged(QString)),this,SLOT(setContent(QString)));
    w_content->blockSignals(false);
    w_content->setReadOnly(!operations()->isEnabled(6));
    vlay->addWidget(new QLabel(tr("Содержание"),widget));
    vlay->addWidget(w_content);
    main->addWidget(gbox);
    if(viewType==Normal)
    {
        QLineEdit* line = new QLineEdit(widget);
        line->setReadOnly(true);
        line->setEnabled(false);
        line->setText(status());
        QHBoxLayout* hlay = new QHBoxLayout;
        hlay->addWidget(new QLabel(tr("Статус"),widget));
        hlay->addStretch();
        hlay->addWidget(line);
        vlay->addLayout(hlay);

        vTable* table = new vTable(widget);
        int n=0;
        for(int i=0;i<childCount();i++)
            if(!child(i)->isHidden()) n++;
        table->setSize(n,4);
        table->setColSettings("5%;55%;20%;15%");
        table->setHorizontalHeaderLabels(QStringList()<<tr("№")<<tr("Причина")<<tr("Инициатор")<<tr("Статус"));
        int k=0;
        for(int i=0;i<childCount();i++)
        {
            Protocol* item = dynamic_cast<Protocol*>(child(i));
            if(item->isHidden())continue;
            table->setCell(k,0,item->num());
            table->setCell(k,1,item->causes());
            if(item->author()!=0)
                table->setCell(k,2,item->author()->name());
            else
                table->setCell(k,2,tr("Ошибка: невозможно назначить инициатора"));
            table->setCell(k,3,item->status());
            k++;
        }
        connect(table,SIGNAL(cellActivated(int,int)),this,SLOT(onTableItemClick(int,int)));
        gbox = new QGroupBox(tr("Протоколы"),widget);
        vlay = new QVBoxLayout;
        vlay->addWidget(table);
        gbox->setLayout(vlay);
        main->addWidget(gbox);
    }
    widget->setLayout(main);
    return widget;
}
void Disparition::setContent(const QString &Content)
{
    m_content=Content;
    emit changed();
}
QString Disparition::content() const
{
    return m_content;
}
void Disparition::onTableItemClick(int row, int column)
{
    emit childWakedUp(dynamic_cast<DocEntity*>(child(row)));
}
QString Disparition::capTemplate()
{
    return tr("Несоответствие");
}
void Disparition::appendProtocol()
{
    Protocol* item = new Protocol(this);
    item->setID(0);
    item->setNum(childCount());
    TreeDoc* tree= dynamic_cast<TreeDoc*>(treeWidget());
    DbConnection::QueryResult res = tree->execute(tr("select =schema=.in_uid()"));
    if(res.success()) item->setAuthor(tree->users()->user(res.at(0,0).toInt()));
    treeWidget()->setCurrentItem(item);
    item->setState(300);
    item->operations()->setEnabled(4,true);
    item->operations()->setEnabled(7,true);
    item->operations()->setEnabled(11,true);
    emit newItem(item);
    emit childWakedUp(item);
}
bool Disparition::saveToDB()
{
    bool ok=isCorrect(), stop=false;
    if(!ok) return false;

    if(id()==0)
    {
        QString sql="select =schema=.ex_append_disparition(%1,%2,'%3'::text)";
         sql=sql.arg(parent()->id()).arg(num()).arg(content());
        DbConnection::QueryResult res = dynamic_cast<TreeDoc*>(treeWidget())->execute(sql);
        if(res.success())
            setID(res.at(0,0).toInt());
        else
            ok=false;
    }
    else
    {
        QString sql="select =schema=.ex_change_disparition(%1,'%2'::text,%3)";
        sql=sql.arg(id()).arg(content()).arg(num());
        DbConnection::QueryResult res = dynamic_cast<TreeDoc*>(treeWidget())->execute(sql);
        ok=res.success();
    }
    if(ok)setChanged(false);
    int i=0;
    while(ok&&!stop)
    {
        stop=(i>=childCount());
        if(!stop) ok=dynamic_cast<DocEntity*>(child(i))->saveToDB();
        i++;
    }
    if(!ok) return false;
    return ok;
}
bool Disparition::isCorrect()
{
    return true;
}
